package com.chart.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chart.chart.domian.ChartColor;
import com.chart.common.core.domain.AjaxResult;
import com.chart.common.utils.SecurityUtils;
import com.chart.common.utils.uuid.IdUtils;
import com.chart.system.mapper.ChartColorMapper;
import com.chart.system.service.ChartColorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * 颜色操作业务层
 */
@Slf4j
@Service
public class ChartColorServiceimpl extends ServiceImpl<ChartColorMapper, ChartColor> implements ChartColorService {


    @Autowired
    private ChartColorMapper chartColorMapper;

    @Override
    @Transactional
    public AjaxResult saveColors(String colorCodes) {
        if (colorCodes.isEmpty()) {
            log.warn("上传的颜色为空，操作中止");
            return AjaxResult.warn("上传的颜色为空，请重新上传!");
        }

        Long userId = SecurityUtils.getUserId();
        log.info("开始为用户 ID: {} 保存颜色, 颜色代码: {}", userId, colorCodes);

        // 查询当前用户是否已有颜色数据
        LambdaQueryWrapper<ChartColor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChartColor::getUserId, userId);
        List<ChartColor> list = list(wrapper);

        // 若已存在记录，则更新颜色
        if (!list.isEmpty()) {
            ChartColor existingColor = list.get(0);
            Integer currentVersion = existingColor.getVersion();  // 获取当前版本号
            log.info("获取到用户ID={}的当前颜色版本号为: {}", userId, currentVersion);

            try {
                // 使用乐观锁的更新方法，传入colorCodes
                boolean result = chartColorMapper.updateColors(userId, colorCodes, currentVersion);
                if (result) {
                    log.info("更新颜色成功，用户ID={}的颜色，颜色代码为: {}", userId, colorCodes);
                    return AjaxResult.success("颜色更新成功");
                } else {
                    log.warn("更新颜色失败，用户ID={}的版本号已过期", userId);
                    return AjaxResult.error("更新失败，请重试！");
                }
            } catch (Exception e) {
                log.error("更新用户颜色失败，用户ID={}，错误信息为: {}", userId, e.getMessage());
                throw new RuntimeException("颜色更新失败，系统异常，请稍后重试");
            }
        } else {
            // 若不存在记录，插入新数据
            ChartColor chartColor = new ChartColor();
            chartColor.setUserId(userId);
            chartColor.setColorCodes(colorCodes);
            chartColor.setVersion(0);
            chartColor.setId(IdUtils.generateRandomNumber());

            try {
                boolean saveResult = save(chartColor);
                if (saveResult) {
                    return AjaxResult.success("颜色保存成功");
                } else {
                    log.warn("保存颜色信息失败，用户ID: {}", userId);
                    return AjaxResult.error("保存失败，请重试！");
                }
            } catch (Exception e) {
                //捕获唯一约束异常（DuplicateKeyException），即用户尝试插入的颜色数据已经存在。确保一个用户插入一条数据。
                if (e.getCause() instanceof org.springframework.dao.DuplicateKeyException) {
                    // 捕获唯一约束异常，转为更新操作
                    log.warn("检测到重复插入，执行更新操作，用户ID: {}", userId);
                    ChartColor existingColor = list(wrapper).get(0);
                    Integer currentVersion = existingColor.getVersion();
                    boolean result = chartColorMapper.updateColors(userId, colorCodes, currentVersion);
                    return result ? AjaxResult.success("颜色更新成功") : AjaxResult.error("更新失败，请重试！");
                }
                log.error("保存颜色信息时发生异常，用户ID: {}，异常信息: {}", userId, e.getMessage(), e);
                throw new RuntimeException("颜色保存失败，系统异常，请稍后重试");
            }

        }
    }


    /**
     * 根据用户id查询颜色
     *
     * @return
     */
    @Override
    public AjaxResult queryColors() {
        Long userId = SecurityUtils.getUserId();
        log.info("查询用户ID为 {} 的颜色数据", userId);
        LambdaQueryWrapper<ChartColor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChartColor::getUserId, userId);
        wrapper.select(ChartColor::getId, ChartColor::getColorCodes, ChartColor::getColorId, ChartColor::getUserId);
        List<ChartColor> list = list(wrapper);
        // 获取查询到的第一个颜色数据的userId，如果列表为空，仍然返回结构一致的响应
        Long userIdFromList = list.isEmpty() ? userId : list.get(0).getUserId();

        // 将颜色代码字符串分割并转换为列表
        ArrayList<List<String>> colorsArray = new ArrayList<>();
        for (ChartColor chartColor : list) {
            String colorCodes = chartColor.getColorCodes();

            String[] colorArray = colorCodes.split(",");
            List<String> colorList = Arrays.asList(colorArray);  // 将数组转换为 List<String>
            colorsArray.add(colorList);
        }
        // 如果列表为空，返回空的颜色数据
        if (colorsArray.isEmpty()) {
            colorsArray.add(new ArrayList<>()); // 空的颜色数组
        }
        // 将数据放入Map中
        HashMap<Object, Object> map = new HashMap<>();
        map.put("colors", colorsArray);
        map.put("userId", userIdFromList);

        log.info("成功查询到用户ID {} 的颜色数据", userId);
        return AjaxResult.success(map);
    }


    @Override
    public AjaxResult updateColors(String colorCodes) {
        if (colorCodes == null || colorCodes.isEmpty()) {
            return AjaxResult.warn("上传的颜色为空，请重新上传!");
        }

        Long userId = SecurityUtils.getUserId();
        log.info("开始更新用户ID={}的颜色，颜色代码为: {}", userId, colorCodes);

        // 根据 userId 查询版本号
        LambdaQueryWrapper<ChartColor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChartColor::getUserId, userId);
        List<ChartColor> list = list(wrapper);

        // 校验用户是否已保存颜色
        if (list.isEmpty()) {
            log.warn("用户ID={}没有已保存的颜色，更新操作中止", userId);
            return AjaxResult.error("该用户没有已保存的颜色，请先添加颜色！");
        }

        // 获取当前版本号
        Integer version = list.get(0).getVersion();
        log.info("获取到用户ID={}的当前颜色版本号为: {}", userId, version);

        // 更新该条数据
        try {
            boolean result = chartColorMapper.updateColors(userId, colorCodes, version);
            log.info("更新颜色成功，用户ID={}的颜色，颜色代码为: {}", userId, colorCodes);
            return result ? AjaxResult.success("颜色更新成功") : AjaxResult.error("颜色更新失败，请重试！");
        } catch (Exception e) {
            log.warn("更新用户颜色失败，用户ID={}，错误信息为={}", userId, e.getMessage());
            throw new RuntimeException("颜色更新失败，请稍后重试！");
        }
    }


}
